/*!
 * Ghost Cursors.js
 * - 90's cursors collection
 * -- https://github.com/tholman/90s-cursor-effects
 * -- http://codepen.io/tholman/full/oYJQZx
 */

(function ghostCursor() {
    var width = window.innerWidth;
    var height = window.innerHeight;
    var cursor = {
        x: width / 2,
        y: width / 2,
    };
    var particles = [];

    function init() {
        bindEvents();
        attachInitialParticleStyles();
        loop();
    }

    // Bind events that are needed
    function bindEvents() {
        document.addEventListener("mousemove", onMouseMove);
        document.addEventListener("touchmove", onTouchMove);
        document.addEventListener("touchstart", onTouchMove);

        window.addEventListener("resize", onWindowResize);
    }

    function onWindowResize(e) {
        width = window.innerWidth;
        height = window.innerHeight;
    }

    function onTouchMove(e) {
        if (e.touches.length > 0) {
            for (var i = 0; i < e.touches.length; i++) {
                addParticle(e.touches[i].clientX, e.touches[i].clientY);
            }
        }
    }

    function onMouseMove(e) {
        cursor.x = e.clientX;
        cursor.y = e.clientY;

        addParticle(cursor.x, cursor.y);
    }

    function addParticle(x, y) {
        var particle = new Particle();
        particle.init(x, y);
        particles.push(particle);
    }

    function updateParticles() {
        // Updated
        for (var i = 0; i < particles.length; i++) {
            particles[i].update();
        }

        // Remove dead particles
        for (var i = particles.length - 1; i >= 0; i--) {
            if (particles[i].lifeSpan < 0) {
                particles[i].die();
                particles.splice(i, 1);
            }
        }
    }

    function loop() {
        requestAnimationFrame(loop);
        updateParticles();
    }

    /**
     * Particles
     */

    function Particle() {
        // How long cursor particle will live for
        this.maxLifeSpan = 80;

        // Will begin fading at this point in the lifespan
        this.fadePoint = 50;

        this.lifeSpan = this.maxLifeSpan;

        // Init, and set properties
        this.init = function(x, y) {
            this.position = {
                x: x - 10,
                y: y - 10,
            };

            this.element = document.createElement("span");
            this.element.className = "particle-cursors";
            this.update();

            document.body.appendChild(this.element);
        };

        this.update = function() {
            this.lifeSpan--;

            this.element.style.transform = "translate3d(" + this.position.x + "px," + this.position.y + "px,0)";

            if (this.lifeSpan < this.fadePoint) {
                this.element.style.opacity = (this.lifeSpan - 1) / (this.fadePoint - 1);
            }
        };

        this.die = function() {
            this.element.parentNode.removeChild(this.element);
        };
    }

    /**
     * Utils
     */

    // Injects initial cursor styles to the head of the page.
    function attachInitialParticleStyles() {
        var initialStyles = [
            ".particle-cursors {",
            "position: absolute;",
            "display: block;",
            "pointer-events: none;",
            "z-index: 1000000;",
            "width: 12px;",
            "height: 19px;",
            "will-change: transform;",
            "background-size: contain;",
            "background-image: url('');",
            "}",
        ].join("");

        var style = document.createElement("style");
        style.type = "text/css";
        style.innerHTML = initialStyles;
        document.getElementsByTagName("head")[0].appendChild(style);
    }

    // Applies css `properties` to an element.
    function applyProperties(target, properties) {
        for (var key in properties) {
            target.style[key] = properties[key];
        }
    }

    init();
})();
